#ifndef TEXTINPUT_H
#define TEXTINPUT_H

#include "UIObject.h"

#include "..\Graphic\HgeGraphic.h"

#include "hge\hgefont.h"
#include "hge\hgesprite.h"
#include "Shape.h"

//extern HGE* hge;

namespace air
{
	class TextInputHgeObject;

	class TextInput : public UIObject
	{
		friend TextInputHgeObject;
	public:
		TextInput(float _x, float _y, float _width, float _height, hgeFont *_fnt, DWORD _color = 0xFF000000, int _capacity = 100, const char *_text = "");
		~TextInput();

		Shape* getShape()
		{ return this->rect; }

		bool TextInput::KeyClick(int key, int chr);

		void SetTextColor(DWORD _color)
		{ color.SetHWColor(_color); }
		void SetBorderColor(DWORD _color)
		{ color.SetHWColor(_color); }
		int  GetSize() const
		{ return size; }
		const char *GetText() const
		{ return text; }
		/// @brief Copy, test for multiline and get size.
		/// Cursor pos was not changed
		/// @return Whether successful. Text will be modified even false.
		bool SetText(const char *_text);

		/// @brief Get the x coord of the control.
		float GetX() const
		{ return rect->getPositionX(); }
		float GetY() const
		{ return rect->getPositionY(); }
		float GetX2() const
		{ return rect->getPositionX2(); }
		float GetY2() const
		{ return rect->getPositionY2(); }
		float GetHeight() const
		{ return rect->H(); }
		float GetWidth() const
		{ return rect->W(); }
		//void SetX(float _x)
		//{ rect.x1 = _x; }
		//void SetY(float _y)
		//{ rect.y1 = _y; }
		//void SetHeight(float _height)
		//{ rect.y2 = rect.y1 + _height; }
		//void SetWidth(float _width)
		//{ rect.x2 = rect.x1 + _width; }
		bool GetMultiLine() const
		{ return isMultiLine; }
		/// @brief If is multiline, press Enter will start a new line.
		/// Else it will call a function you specificated or do nothing
		void SetMultiLine(bool _isMultiLine)
		{
			isMultiLine = _isMultiLine;
			updateCursorPos();
		}
		void SetMaxSize(int _maxSize)
		{
			// TODO: multiline and auto wrap
			if (_maxSize < size)
				maxSize = size;
			maxSize = _maxSize;
		}
		int GetMaxSize() const
		{ return maxSize; }

		/// @brief text color
		hgeColor	color;
		hgeColor	borderColorNorm;
		hgeColor	borderColorOver;
		hgeColor	borderColorFocused;
		/// @brief distance between the text and the border
		float		padTop;
		float		padLeft;
		/// @brief for tuning cursor position
		float		cursorXOffset;
		float		cursorYOffset;
		/// @brief must be greater than zero
		float		blinkInterval;
		/// @brief whether TAB key insert tab, default false
		bool        tabInsert;

		/// @brief the function to call when Enter is pressed in single
		/// line mode
		void        (*enterHook)();

	private:
		TextInput(const TextInput &rhs);
		TextInput& operator=(const TextInput &rhs);

		bool expand();
		void updateCursorPos();

		bool insertChr(int chr);
		bool backspace();
		bool backwardChar();
		bool forwardChar();
		bool deleteChar();

		hgeColor	borderColor;
		
		int		pos;
		bool	focused;
		float	cursorX;
		float	cursorY;
		bool	isMultiLine;

		char	*text;
		int		size;
		int		capacity;
		int		maxSize;

		float	blinkCounter;

		hgeFont		*fnt;
		Rect*	rect;
	};

	class TextInputHgeObject : public IGraphicObject
	{
	public:
		TextInputHgeObject(TextInput*);
		~TextInputHgeObject();

		virtual bool initialize(Graphic* graphic);
		virtual void render();
	private:
		hgeFont*	fnt;
		HGE*		hge;
		TextInput*	tiObj;
	};
}

#endif /* TEXTINPUT_H */
